<template>
  <div class="step-container">
    <div class="content-card">
      <!-- 标题区域 -->
      <div class="header-section">
        <h2 class="main-title">知识图谱生成</h2>
        <p class="subtitle">从文本内容中提取知识点，构建知识体系</p>
      </div>

      <!-- 学科选择区域 -->
      <div class="subject-section">
        <h3 class="section-title">
          <el-icon><Reading /></el-icon>
          选择学科
        </h3>
        <el-select
          v-model="selectedSubject"
          placeholder="请选择要生成知识图谱的学科"
          class="subject-select"
        >
          <el-option
            v-for="item in subjectList"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </div>

      <!-- 内容输入区域 -->
      <div class="content-section">
        <h3 class="section-title">
          <el-icon><Document /></el-icon>
          输入内容
        </h3>
        
        <!-- 文件上传按钮 -->
        <div class="upload-section">
          <el-upload
            class="upload-file"
            action="#"
            :auto-upload="false"
            :show-file-list="false"
            accept=".txt,.doc,.docx,.pdf"
            :before-upload="handleBeforeUpload"
            @change="handleFileChange"
          >
            <el-button type="primary" plain>
              <el-icon><Upload /></el-icon>
              导入文档
            </el-button>
            <template #tip>
              <div class="upload-tip">支持 .txt、.doc、.docx、.pdf 格式文件，大小不超过10MB</div>
            </template>
          </el-upload>
        </div>

        <!-- 文本输入框 -->
        <el-input
          v-model="textContent"
          type="textarea"
          :rows="10"
          maxlength="3000"
          show-word-limit
          clearable
          placeholder="在这里输入或粘贴文本内容，系统将自动分析并生成知识图谱"
          class="content-input"
        />
      </div>

      <!-- 生成按钮和进度区域 -->
      <div class="action-section">
        <el-button 
          type="primary"
          :loading="generating"
          :disabled="!canGenerate"
          size="large"
          class="generate-button"
          @click="handleGenerate"
        >
          <template #icon>
            <el-icon><Connection /></el-icon>
          </template>
          {{ generating ? '正在生成知识图谱...' : '开始生成知识图谱' }}
        </el-button>

        <!-- 生成进度显示 -->
        <div v-if="generating" class="progress-section">
          <el-progress 
            :percentage="progress" 
            :status="progressStatus"
            :stroke-width="15"
            :format="progressFormat"
          />
          <div class="progress-info">
            <p class="progress-text">{{ progressMessage }}</p>
            <p v-if="pointsGenerated > 0" class="points-stats">
              已生成 <span class="highlight">{{ pointsGenerated }}</span> 个知识点
            </p>
          </div>
        </div>
      </div>

      <!-- 生成的数据表格预览 -->
      <div class="data-section" v-if="graphDataList.length > 0">
        <div class="data-header">
          <h3 class="section-title">
            <el-icon><DataAnalysis /></el-icon>
            已生成知识点
          </h3>
          <div class="data-actions">
            <el-button type="success" size="small" @click="viewFullGraph">
              <el-icon><View /></el-icon>
              查看完整知识图谱/试题生成
            </el-button>
          </div>
        </div>

         <!-- 数据表格 -->
         <el-table
          :data="paginatedData"
          border
          stripe
          highlight-current-row
          style="width: 100%"
          v-loading="loading"
          class="knowledge-table"
        >
          <el-table-column prop="subjectName" label="课程" width="100" />
          <el-table-column prop="chapter" label="章" width="60" sortable align="center" />
          <el-table-column prop="node" label="节" width="60" sortable align="center" />
          <el-table-column prop="knowledge" label="知识点" min-width="220" show-overflow-tooltip />
          <el-table-column prop="mastery" label="掌握程度" width="120" align="center">
            <template #default="scope">
              <el-tag :type="getMasteryTagType(scope.row.mastery)" effect="dark" size="small">
                {{ scope.row.mastery }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="difficulty" label="难度系数" width="120" sortable align="center">
            <template #default="scope">
              <el-rate
                v-model="scope.row.difficulty"
                disabled
                :max="3"
                :colors="difficultyColors"
                text-color="#909399"
              />
            </template>
          </el-table-column>
          <el-table-column label="操作" width="160" align="center">
            <template #default="scope">
              <div class="table-actions">
                <el-button
                  size="small"
                  type="primary"
                  circle
                  @click="handleEdit(scope.row)"
                  title="编辑"
                >
                  <el-icon><Edit /></el-icon>
                </el-button>
                <el-button
                  size="small"
                  type="danger"
                  circle
                  @click="handleDelete(scope.row)"
                  title="删除"
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
        
        <!-- 分页控件 -->
        <div class="pagination-wrapper">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next, jumper"
            :total="filteredData.length"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            background
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { Document, Upload, Reading, Connection, DataAnalysis, View, Edit, Delete } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { request } from '../../api/request'
import { getSubjects } from '../../api/subject'
import { generateGraphDataStream } from '../../api/ai'

const router = useRouter()

// 响应式数据
const textContent = ref('')
const selectedSubject = ref(null)
const subjectList = ref([])
const loading = ref(false)
const generating = ref(false)
const progress = ref(0)
const progressMessage = ref('')
const progressStatus = ref('')
const graphDataList = ref([])
const pointsGenerated = ref(0)
const processingStage = ref('准备中')

// 定义颜色和标签类型
const difficultyColors = ['#67C23A', '#E6A23C', '#F56C6B']
const masteryTagMap = {
  '了解': 'info',
  '理解': 'success',
  '掌握': 'primary',
  '应用': 'warning',
}

// 分页相关
const currentPage = ref(1)
const pageSize = ref(10)
const searchKeyword = ref('')
const filterChapter = ref(null)
const filterMastery = ref(null)

// 计算属性：是否可以生成
const canGenerate = computed(() => {
  return selectedSubject.value && textContent.value.trim().length > 0
})

// 进度条格式化
const progressFormat = (percentage) => {
  if (percentage === 100) {
    return '完成'
  }
  return `${percentage}%`
}

// 获取学科列表
const getSubjectList = async () => {
  try {
    const user = JSON.parse(localStorage.getItem('user'))
    if (!user) {
      ElMessage.error('请先登录')
      return
    }
    const response = await getSubjects(user.id, 1, 100)
    if (response.code === 200) {
      subjectList.value = response.data.list
    } else {
      ElMessage.error(response.message || '获取学科列表失败')
    }
  } catch (error) {
    console.error('获取学科列表失败', error)
    ElMessage.error('获取学科列表失败')
  }
}

// 文件类型验证
const handleBeforeUpload = (file) => {
  const allowedTypes = [
    'text/plain',
    'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/pdf'
  ]
  
  const fileName = file.name.toLowerCase()
  const fileExt = fileName.substring(fileName.lastIndexOf('.'))
  
  if (!allowedTypes.includes(file.type) && 
      !['.txt', '.doc', '.docx', '.pdf'].includes(fileExt)) {
    ElMessage.error('只支持 txt、doc、docx、pdf 格式的文件！')
    return false
  }
  
  const maxSize = 10 * 1024 * 1024
  if (file.size > maxSize) {
    ElMessage.error('文件大小不能超过10MB！')
    return false
  }
  
  return true
}

// 处理文件上传
const handleFileChange = async (file) => {
  loading.value = true
  if (!file) return
  
  try {
    if (file.raw.type === 'text/plain') {
      const reader = new FileReader()
      reader.onload = (e) => {
        textContent.value = e.target.result
      }
      reader.readAsText(file.raw)
    } else {
      ElMessage.success('文件上传成功，等待处理...')
      const res = await request.upload('/ai/upload', file.raw)
      textContent.value = res.data
    }
  } catch (error) {
    ElMessage.error('文件读取失败！')
    console.error('文件读取错误:', error)
  } finally {
    loading.value = false
  }
}

// 处理知识图谱生成
const handleGenerate = async () => {
  if (!canGenerate.value) {
    ElMessage.warning('请先选择学科并输入或上传内容')
    return
  }

  // 确认对话框
  ElMessageBox.confirm(
    '生成知识图谱可能需要几分钟时间，是否继续？',
    '提示',
    {
      confirmButtonText: '继续',
      cancelButtonText: '取消',
      type: 'info'
    }
  ).then(() => {
    startGeneration()
  }).catch(() => {
    // 用户取消操作
  })
}

// 开始生成知识图谱
const startGeneration = async () => {
  generating.value = true
  progress.value = 0
  processingStage.value = '准备中'
  progressMessage.value = '正在开始生成知识图谱...'
  progressStatus.value = ''
  graphDataList.value = []
  pointsGenerated.value = 0

  try {
    const graphRequest = {
      message: textContent.value,
      subjectId: selectedSubject.value
    }

    const provider = localStorage.getItem('aiModel') || 'deepseek'
    
    const baseUrl = import.meta.env.VITE_API_BASE_URL || ''
    
    // 创建一个URLSearchParams对象，用于携带provider参数
    const params = new URLSearchParams()
    params.append('provider', provider)
    
    // 创建请求URL
    const url = `${baseUrl}/ai/generate/graph/stream?${params.toString()}`
    
    // 发送POST请求
    const xhr = new XMLHttpRequest()
    xhr.open('POST', url, true)
    xhr.setRequestHeader('Content-Type', 'application/json')
    xhr.responseType = 'text'
    xhr.timeout = 900000 // 15分钟超时
    
    // 用于保存事件流部分
    let receivedData = ''
    let error = null
    let isCompleted = false
    
    // 最后一次接收数据的时间戳
    let lastDataTimestamp = Date.now()
    
    // 设置一个检查连接活跃度的定时器
    const activityChecker = setInterval(() => {
      const inactiveTime = Date.now() - lastDataTimestamp
      // 如果30秒没有新数据，发送心跳保持连接
      if (inactiveTime > 30000) {
        console.log('30秒无活动，发送心跳检查')
        // 触发UI更新保持连接活跃
        if (window.dispatchEvent) {
          window.dispatchEvent(new Event('heartbeat'))
        }
      }
      
      // 如果3分钟没有新数据，认为连接可能已死亡
      if (inactiveTime > 180000) {
        console.warn('连接3分钟无活动，可能已断开')
        clearInterval(activityChecker)
        if (!isCompleted) {  // 只有在尚未完成的情况下才中止
          xhr.abort()
          handleGenerationError('连接超时，长时间没有接收到数据')
        }
      }
    }, 30000)  // 每30秒检查一次
    
    xhr.onprogress = function() {
      // 更新活跃时间戳
      lastDataTimestamp = Date.now()
      
      // 将新接收的数据添加到已接收数据中
      const newData = xhr.responseText.substring(receivedData.length)
      receivedData = xhr.responseText
      
      // 解析事件流
      const lines = newData.split('\n')
      for (let i = 0; i < lines.length; i++) {
        const line = lines[i].trim()
        if (line.startsWith('data:')) {
          try {
            const eventData = line.substring(5).trim()
            
            // 心跳消息处理
            if (eventData === 'processing') {
              console.log('收到服务器心跳')
              continue
            }
            
            // 检查是否是事件对象
            if (eventData.startsWith('{') && eventData.includes('"name"')) {
              const event = JSON.parse(eventData)
              if (event.name === 'data') {
                // 收到数据事件
                const data = Array.isArray(event.data) ? event.data : JSON.parse(event.data)
                
                // 对每个知识点进行处理
                if (Array.isArray(data)) {
                  // 将新的知识点添加到总数据集中
                  graphDataList.value.push(...data)
                  pointsGenerated.value += data.length
                  
                  // 更新进度信息
                  processingStage.value = '知识点分析'
                  progressMessage.value = `正在分析文本并提取知识点...`
                  
                  // 更新进度条 - 根据已生成点数动态调整
                  // 假设平均每次生成约50-100个点，设置期望上限
                  const expectedTotal = Math.max(100, pointsGenerated.value * 1.2)
                  progress.value = Math.min(90, Math.floor((pointsGenerated.value / expectedTotal) * 90))
                }
              } else if (event.name === 'error') {
                // 收到错误事件
                error = event.data
                console.error('错误:', error)
                handleGenerationError(error)
              } else if (event.name === 'complete') {
                // 收到完成事件
                console.log('完成:', event.data)
                isCompleted = true
                
                // 更新UI显示
                progress.value = 100
                progressStatus.value = 'success'
                progressMessage.value = `知识图谱生成完成，共生成${pointsGenerated.value}个知识点`
                processingStage.value = '已完成'
                
                ElMessage.success(event.data)
                
                // // 3秒后自动跳转
                // setTimeout(() => {
                //   if (generating.value) {
                //     generating.value = false
                //     router.push({
                //       path: '/graph',
                //       query: {
                //         subjectId: selectedSubject.value
                //       }
                //     })
                //   }
                // }, 3000)
                
                // 主动关闭连接
                clearInterval(activityChecker)
                xhr.abort()
                
              } else if (event.name === 'progress') {
                // 收到进度事件
                console.log('进度:', event.data)
                // 替换ElMessage以避免过多通知
                progressMessage.value = event.data
              } else if (event.name === 'heartbeat') {
                // 收到心跳事件
                console.log('心跳:', event.data)
                lastDataTimestamp = Date.now() // 刷新时间戳
              } else if (event.name === 'warning') {
                // 收到警告事件
                console.warn('警告:', event.data)
                ElMessage.warning(event.data)
              }
            }
          } catch (e) {
            console.error('解析事件数据失败:', e, line)
          }
        }
      }
    }
    
    xhr.onload = function() {
      clearInterval(activityChecker)
      if (!isCompleted) {  // 只有在尚未完成的情况下才处理
        if (xhr.status === 200) {
          if (error) {
            handleGenerationError(error)
          } else if (graphDataList.value.length > 0) {
            // 显示成功信息
            progress.value = 100
            progressStatus.value = 'success'
            progressMessage.value = `知识图谱生成完成，共生成${pointsGenerated.value}个知识点`
            
            ElMessage.success('知识图谱生成完成')
            
            setTimeout(() => {
              generating.value = false
            }, 2000)
          } else {
            handleGenerationError('未能生成任何知识点，请尝试修改输入内容或选择其他学科')
          }
        } else {
          handleGenerationError(`请求失败: ${xhr.status} ${xhr.statusText}`)
        }
      }
    }
    
    xhr.ontimeout = function() {
      clearInterval(activityChecker)
      if (!isCompleted) {
        handleGenerationError('请求超时，服务器处理时间过长')
      }
    }
    
    xhr.onerror = function() {
      clearInterval(activityChecker)
      if (!isCompleted) {
        handleGenerationError('网络请求失败，请检查网络连接')
      }
    }
    
    xhr.onabort = function() {
      clearInterval(activityChecker)
      if (!isCompleted) {
        handleGenerationError('请求被中止')
      }
    }
    
    // 发送请求体
    xhr.send(JSON.stringify(graphRequest))

  } catch (error) {
    handleGenerationError(error.message)
  }
}

// 错误处理函数
const handleGenerationError = (message) => {
  generating.value = false
  progressStatus.value = 'exception'
  progressMessage.value = `生成失败: ${message}`
  ElMessage.error(`生成知识图谱失败: ${message}`)
}

// 获取掌握程度标签类型
const getMasteryTagType = (mastery) => {
  return masteryTagMap[mastery] || 'info'
}

// 查看完整知识图谱
const viewFullGraph = () => {
  router.push({
    path: '/graph',
    query: {
      subjectId: selectedSubject.value
    }
  })
}

// 处理每页数量变化
const handleSizeChange = (val) => {
  pageSize.value = val
  currentPage.value = 1 // 重置到第一页
}

// 处理页码变化
const handleCurrentChange = (val) => {
  currentPage.value = val
}

// 编辑知识点（占位函数）
const handleEdit = (row) => {
  ElMessage.info('编辑功能将在知识图谱页面实现')
}

// 删除知识点（占位函数）
const handleDelete = (row) => {
  ElMessage.info('删除功能将在知识图谱页面实现')
}

// 筛选后的数据
const filteredData = computed(() => {
  let result = graphDataList.value
  
  // 关键字搜索
  if (searchKeyword.value) {
    const keyword = searchKeyword.value.toLowerCase()
    result = result.filter(item => 
      item.knowledge.toLowerCase().includes(keyword)
    )
  }
  
  // 章节筛选
  if (filterChapter.value) {
    result = result.filter(item => item.chapter === filterChapter.value)
  }
  
  // 掌握程度筛选
  if (filterMastery.value) {
    result = result.filter(item => item.mastery === filterMastery.value)
  }
  
  return result
})

// 当前页数据
const paginatedData = computed(() => {
  const startIndex = (currentPage.value - 1) * pageSize.value
  return filteredData.value.slice(startIndex, startIndex + pageSize.value)
})

// 组件挂载时获取学科列表
onMounted(() => {
  getSubjectList()
})
</script>

<style scoped>
.step-container {
  min-height: 100vh;
  /* padding: 24px; */
  background-color: #f5f7fa;
}

.content-card {
  margin: 0 auto;
  background: #ffffff;
  border-radius: 12px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  padding: 32px;
}

.pagination-wrapper {
  padding: 16px 20px;
  display: flex;
  justify-content: flex-end;
  background-color: #fff;
  border-top: 1px solid #ebeef5;
}

.header-section {
  text-align: center;
  margin-bottom: 40px;
}

.main-title {
  font-size: 28px;
  font-weight: 600;
  color: #303133;
  margin: 0;
}

.subtitle {
  margin-top: 8px;
  font-size: 16px;
  color: #909399;
}

.section-title {
  display: flex;
  align-items: center;
  font-size: 18px;
  font-weight: 500;
  color: #303133;
  margin-bottom: 16px;
}

.section-title .el-icon {
  margin-right: 8px;
  font-size: 20px;
  color: #409EFF;
}

.subject-section {
  margin-bottom: 32px;
  padding: 24px;
  background: #f8f9fa;
  border-radius: 8px;
}

.subject-select {
  width: 100%;
  max-width: 400px;
}

.content-section {
  margin-bottom: 32px;
}

.upload-section {
  margin-bottom: 16px;
}

.upload-tip {
  margin-top: 8px;
  font-size: 13px;
  color: #909399;
}

.content-input {
  margin-top: 16px;
}

:deep(.el-textarea__inner) {
  font-size: 15px;
  line-height: 1.6;
  padding: 16px;
  background-color: #fafafa;
  border: 1px solid #e4e7ed;
  transition: all 0.3s ease;
}

:deep(.el-textarea__inner:focus) {
  background-color: #ffffff;
  border-color: #409EFF;
}

.action-section {
  text-align: center;
}

.generate-button {
  width: 100%;
  max-width: 400px;
  height: 48px;
  font-size: 16px;
}

.progress-section {
  margin-top: 24px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 8px;
}

.progress-info {
  margin-top: 16px;
}

.progress-text {
  color: #606266;
  font-size: 14px;
  text-align: center;
  margin-bottom: 8px;
}

.points-stats {
  color: #606266;
  font-size: 14px;
  text-align: center;
}

.highlight {
  color: #409EFF;
  font-weight: 600;
}

.data-section {
  margin-top: 32px;
  border-top: 1px solid #ebeef5;
  padding-top: 24px;
}

.data-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.knowledge-table {
  margin-top: 16px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .content-card {
    padding: 20px;
  }

  .main-title {
    font-size: 24px;
  }

  .subtitle {
    font-size: 14px;
  }

  .section-title {
    font-size: 16px;
  }

  .subject-section,
  .content-section {
    padding: 16px;
  }

  .generate-button {
    width: 100%;
  }
  
  .data-header {
    flex-direction: column;
    gap: 12px;
  }
}
</style>